local assets =
{
    Asset("ANIM", "anim/doro_sword.zip"),
    --Asset("ANIM", "anim/swap_spear.zip"),
}
local doro_shadowprotectorbrain = require "brains/doro_shadowprotectorbrain"
local function onhitothers_shadow(player, data) --吸血：1%
    local damage = data and data.damage
    if damage and damage > 0 then
        if player.components.health then
            player.components.health:DoDelta(damage * 0.01)
        end
    end
end
local function onequip_shadow(inst, owner)
    owner.AnimState:OverrideSymbol("swap_object", "doro_sword", "doro_sword")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")

    owner:RemoveEventCallback("onhitother", onhitothers_shadow)
    owner:ListenForEvent("onhitother", onhitothers_shadow)

    if owner.components.hunger then
        owner.components.hunger.burnratemodifiers:SetModifier(inst, 10, "onequip_shadow")
    end
end

local function onunequip_shadow(inst, owner)
    owner.AnimState:ClearOverrideSymbol("swap_object")
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")

    owner:RemoveEventCallback("onhitother", onhitothers_shadow)
    if owner.components.hunger then
        owner.components.hunger.burnratemodifiers:RemoveModifier(inst, "onequip_shadow")
    end
end
local function addToArmy(player, protector)
    player.doro_shadowprotector_list = player.doro_shadowprotector_list or {}
    player.doro_shadowprotector_list[protector] = protector
end
local function removeArmy(player, protector)
    player.doro_shadowprotector_list = player.doro_shadowprotector_list or {}
    player.doro_shadowprotector_list[protector] = nil
end
local function checkFollowerNums(player)
    if player and player.doro_shadowprotector_list then
        local num = 0
        for k, v in pairs(player.doro_shadowprotector_list) do
            if v and v:IsValid() then
                num = num + 1
            end
        end
        return num < 8
    end
    return true
end
local soundsmap = {
    ['ghl/untitled/ghl'] = 1,
    ['bendan/untitled/bendan'] = 1,
    ['zhutou/untitled/zhutou'] = 1,
}
local function playsound(attacker)
    if attacker.SoundEmitter and not attacker.playing_ghl --[[ and not attacker.SoundEmitter:PlayingSound("ghl") ]] then
        attacker.SoundEmitter:PlaySound(weighted_random_choice(soundsmap) --[[ , "ghl" ]])
        attacker.playing_ghl = true
        attacker:DoTaskInTime(1, function()
            attacker.playing_ghl = false
        end)
    end
end
local function onattack_m(inst, attacker, target)
    playsound(attacker)
end
local function onattack_shadow(inst, attacker, target)
    playsound(attacker)
    if attacker and target then
        if (math.random() < 0.2) --[[ or true ]] and checkFollowerNums(attacker) then
            local x, y, z = attacker.Transform:GetWorldPosition()
            local doro_shadowprotector = SpawnPrefab("doro_shadowprotector")
            addToArmy(attacker, doro_shadowprotector)
            if doro_shadowprotector.SaveSpawnPoint ~= nil then
                doro_shadowprotector:SaveSpawnPoint()
            end
            if attacker.components.leader then
                attacker.components.leader:AddFollower(doro_shadowprotector)
            end
            doro_shadowprotector.Physics:Teleport(x, y, z)
            doro_shadowprotector.components.skinner:CopySkinsFromPlayer(attacker)
            doro_shadowprotector.components.combat:SetTarget(attacker)
            doro_shadowprotector.sg:GoToState("lunge_pre", target)
            doro_shadowprotector:ListenForEvent("onremove",
                function() removeArmy(attacker, doro_shadowprotector) end)
        end
    end
end

local function commonfn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("doro_sword")
    inst.AnimState:SetBuild("doro_sword")
    inst.AnimState:PlayAnimation("idle")

    inst:AddTag("sharp")

    --weapon (from weapon component) added to pristine state for optimization
    inst:AddTag("weapon")

    inst:AddTag("nosteal")

    inst:AddTag("stickygrip")

    inst:AddTag("doro_orangeweapon")

    MakeInventoryFloatable(inst, "med", 0.05, { 1.1, 0.5, 1.1 }, true, -9)

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end
    inst:AddComponent("weapon")
    -------

    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.grabbableoverridetag = "doro"

    inst:AddComponent("equippable")

    MakeHauntableLaunch(inst)

    return inst
end
local function onblink(staff, pos, caster)
    local x, y, z = caster.Transform:GetWorldPosition()
    local decoy = SpawnPrefab("doro_decoy")
    decoy.components.health:SetMaxHealth(caster.components.health.maxhealth)
    decoy.Transform:SetPosition(x, y, z)
    decoy:SetOwner(caster)
end
local function OnDischarged(inst)
    inst:AddTag("oncooldown")
end

local function OnCharged(inst)
    inst:RemoveTag("oncooldown")
end
local function doro_weapon_shadow()
    local inst = commonfn()
    inst:AddTag("doro_weapon_shadow")
    if not TheWorld.ismastersim then
        return inst
    end
    inst:AddComponent("rechargeable")
    inst.components.rechargeable:SetOnDischargedFn(OnDischarged)
    inst.components.rechargeable:SetOnChargedFn(OnCharged)

    inst:AddComponent("blinkstaff")
    inst.components.blinkstaff:SetFX("sand_puff_large_front", "sand_puff_large_back")
    inst.components.blinkstaff.onblinkfn = onblink

    inst.components.weapon:SetDamage(TUNING.DORO_WEAPON_DAMAGE_SHADOW)
    inst.components.weapon:SetRange(TUNING.DORO_WEAPON_RANGE_SHADOW)
    inst.components.weapon:SetOnAttack(onattack_shadow)

    inst.components.equippable.walkspeedmult = 1.35

    inst.components.equippable:SetOnEquip(onequip_shadow)
    inst.components.equippable:SetOnUnequip(onunequip_shadow)
    return inst
end
local function collidesDirty(inst, get)
    if get then
        inst.Physics:ClearCollidesWith(COLLISION.OBSTACLES)
        inst.Physics:ClearCollidesWith(COLLISION.WORLD)
        inst.Physics:ClearCollidesWith(COLLISION.SMALLOBSTACLES)
        inst.Physics:ClearCollidesWith(COLLISION.CHARACTERS)
        inst.Physics:ClearCollidesWith(COLLISION.GIANTS)
        inst.Physics:CollidesWith(COLLISION.GROUND)
    else
        inst.Physics:CollidesWith(COLLISION.OBSTACLES)
        inst.Physics:CollidesWith(COLLISION.WORLD)
        inst.Physics:CollidesWith(COLLISION.SMALLOBSTACLES)
        inst.Physics:CollidesWith(COLLISION.CHARACTERS)
        inst.Physics:CollidesWith(COLLISION.GIANTS)

        inst.Physics:CollidesWith(COLLISION.GROUND)
        --inst.Physics:ClearCollidesWith(COLLISION.GROUND)
    end
end
local function OnCollide(inst, other)
    --print("OnCollide", inst, other)
    collidesDirty(inst, true)
end
local function onequip_mountain(inst, owner)
    owner.AnimState:OverrideSymbol("swap_object", "doro_sword", "doro_sword")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")

    owner.doro_ignorecontrol = true
    --无视碰撞体积
    if owner.Physics then
        collidesDirty(owner, true)
        owner.Physics:SetCollisionCallback(OnCollide)
    end
    --踏水
    if owner.components.drownable then
        owner.components.drownable.enabled = false
    end
    --冰冻
    if owner.components.freezable then
        owner.components.freezable:SetRedirectFn(function()
            return true
        end)
    end
    --着火
    owner:AddTag("fireimmune")

    --召唤八个飞剑环绕玩家
    local x, y, z = owner.Transform:GetWorldPosition()
    for i = 1, 8 do
        local doro_fly_sword = SpawnPrefab("doro_fly_sword")
        doro_fly_sword.Transform:SetPosition(x, y, z)
        doro_fly_sword:SetOwner(owner)
        doro_fly_sword:ListenForEvent("sowrd_retire", function()
            if doro_fly_sword.eroding then return end
            doro_fly_sword.eroding = true
            ErodeAway(doro_fly_sword)
            if doro_fly_sword.OnRetire then
                doro_fly_sword.OnRetire(doro_fly_sword, owner)
            end
        end, owner)
        doro_fly_sword:ListenForEvent("onremove", function()
            doro_fly_sword:Remove()
        end, inst)
    end
end

local function onunequip_mountain(inst, owner)
    owner.AnimState:ClearOverrideSymbol("swap_object")
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")

    owner.doro_ignorecontrol = nil
    if owner.Physics then
        collidesDirty(owner, false)
        owner.Physics:SetCollisionCallback(nil)
    end
    if owner.components.drownable then
        owner.components.drownable.enabled = true
    end
    if owner.components.freezable then
        owner.components.freezable:SetRedirectFn(nil)
    end
    owner:RemoveTag("fireimmune")

    owner:PushEvent("sowrd_retire")
    owner.doro_swordtable = {}
    owner.sword_nums = 0
end
local function doro_weapon_mountain()
    local inst = commonfn()
    inst:AddTag("doro_weapon_mountain")
    if not TheWorld.ismastersim then
        return inst
    end
    inst.components.weapon:SetDamage(TUNING.DORO_WEAPON_DAMAGE_MOUNTAIN)
    inst.components.weapon:SetRange(TUNING.DORO_WEAPON_RANGE_MOUNTAIN)
    inst.components.weapon:SetOnAttack(onattack_m)

    inst.components.equippable.walkspeedmult = 2

    inst.components.equippable:SetOnEquip(onequip_mountain)
    inst.components.equippable:SetOnUnequip(onunequip_mountain)
    return inst
end
local function doro_shadowprotector()
    local inst = Prefabs.shadowprotector.fn()

    if not TheWorld.ismastersim then
        return inst
    end
    inst.components.combat:SetDefaultDamage(0)
    inst.components.combat.SetDefaultDamage = function(...)
    end

    inst.components.health:SetMaxHealth(1200)

    inst:AddComponent("planardamage")
    inst.components.planardamage:SetBaseDamage(100)
    inst:SetBrain(doro_shadowprotectorbrain)
    inst.persists = false
    return inst
end
--doro_decoy
return Prefab("doro_weapon_shadow", doro_weapon_shadow, assets),
    Prefab("doro_weapon_mountain", doro_weapon_mountain, assets),
    Prefab("doro_shadowprotector", doro_shadowprotector, assets)
